<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="fS0rC" id="fS0rC"><span data-lake-id="uf6017300" id="uf6017300">典型回答</span></h1>
  <p data-lake-id="u7e9734e8" id="u7e9734e8"><span data-lake-id="uf4adb154" id="uf4adb154">对称加密，指的是需要对加密和解密使用相同密钥的加密算法。</span></p>
  <p data-lake-id="uee0605b2" id="uee0605b2"><br></p>
  <p data-lake-id="ueff4c08a" id="ueff4c08a"><span data-lake-id="u3b8fa227" id="u3b8fa227">最简单的对称加密算法就是通过ASCII码的变化进行密码保存，比如把</span><code data-lake-id="ubed984ab" id="ubed984ab"><span data-lake-id="u27e7541a" id="u27e7541a">abcde</span></code><span data-lake-id="ua803bab7" id="ua803bab7">转换成</span><code data-lake-id="u9c9ec431" id="u9c9ec431"><span data-lake-id="u4def2895" id="u4def2895">bcdef</span></code><span data-lake-id="uaf0657b7" id="uaf0657b7">，其加密算法就是把ASCII码增加1 。</span></p>
  <p data-lake-id="ua0289572" id="ua0289572"><br></p>
  <p data-lake-id="u45148418" id="u45148418"><span data-lake-id="uebded110" id="uebded110">这种加密算法，有一个特点，就是可以根据加密后得到的密文，再根据密钥还原出明文。</span></p>
  <p data-lake-id="u9c8f19c9" id="u9c8f19c9"><span data-lake-id="u9b1c445b" id="u9b1c445b">​</span><br></p>
  <p data-lake-id="u50a70dc8" id="u50a70dc8"><span data-lake-id="uf01a074f" id="uf01a074f">非对称加密，指的是加密和解密使用不同密钥的加密算法，也称为公私钥加密。 </span></p>
  <p data-lake-id="u3bf35228" id="u3bf35228"><span data-lake-id="ua704c407" id="ua704c407">​</span><br></p>
  <h1 data-lake-id="h4BWN" id="h4BWN"><span data-lake-id="ucec2ccdd" id="ucec2ccdd">扩展知识</span></h1>
  <h3 data-lake-id="G0nYA" id="G0nYA"><span data-lake-id="u5bfb54f9" id="u5bfb54f9">明文密码</span></h3>
  <p data-lake-id="u66f6f62e" id="u66f6f62e"><br></p>
  <p data-lake-id="u25be04c2" id="u25be04c2"><span data-lake-id="u72bbfc30" id="u72bbfc30">明文密码就是直接可以看懂的，比如</span><code data-lake-id="u97574bf6" id="u97574bf6"><span data-lake-id="u7f44e602" id="u7f44e602">123456</span></code><span data-lake-id="u486a200a" id="u486a200a">，</span><code data-lake-id="ub38eefd7" id="ub38eefd7"><span data-lake-id="ub380193c" id="ub380193c">admin</span></code><span data-lake-id="u8e13dd37" id="u8e13dd37">等等，而不是经过加密显示出</span><code data-lake-id="u254edee3" id="u254edee3"><span data-lake-id="u26c0ee81" id="u26c0ee81">****</span></code><span data-lake-id="ucd579fac" id="ucd579fac">的内容，这种叫做暗码。比如</span><code data-lake-id="u2a1c0435" id="u2a1c0435"><span data-lake-id="ub524cfed" id="ub524cfed">abc</span></code><span data-lake-id="u9abe0c49" id="u9abe0c49">代表</span><code data-lake-id="ua36ffa2b" id="ua36ffa2b"><span data-lake-id="uc59aa96e" id="uc59aa96e">123</span></code><span data-lake-id="ua18608db" id="ua18608db">，如果告诉你</span><code data-lake-id="u1325818e" id="u1325818e"><span data-lake-id="u50a91f7b" id="u50a91f7b">abc</span></code><span data-lake-id="ua2efe5d4" id="ua2efe5d4">而不告诉你解码规则，你就不能翻译出真正的密码</span><code data-lake-id="u384da797" id="u384da797"><span data-lake-id="u2c39a47f" id="u2c39a47f">123</span></code><span data-lake-id="uf3001cc0" id="uf3001cc0">。</span></p>
  <p data-lake-id="u342f2c33" id="u342f2c33"><br></p>
  <p data-lake-id="u116a28cd" id="u116a28cd"><span data-lake-id="u782f42f3" id="u782f42f3">很多网站都有注册登录功能，对于用户在注册的时候，填写的用户名和密码，如果不经过任何处理直接保存到数据库中，这种情况下，保存的就是用户的明文密码。</span></p>
  <p data-lake-id="u8568e4f1" id="u8568e4f1"><br></p>
  <p data-lake-id="u86655053" id="u86655053"><span data-lake-id="u229b012e" id="u229b012e">这样直接把用户的明文密码保存下来，对于程序开发来说是很方便的。用户在登录的时候直接到数据库中进行账号密码匹配就可以了。但是，同时也埋下了很大的隐患，一旦数据库信息泄露，那么黑客就可以拿到所有用户的用户名和密码。</span></p>
  <p data-lake-id="u06253fd9" id="u06253fd9"><br></p>
  <p data-lake-id="ua4874766" id="ua4874766"><span data-lake-id="u8d832bad" id="u8d832bad">Q:使用明文保存密码好像真的有很大坑，那如何解决呢 A：这个也简单，就对用户密码进行加密就可以了。 Q：加密后保存，那用户密码不就变了了吗，还能正常登录吗？ A：这个简单，每次验密的时候都加密，使用密文匹配就行了。</span></p>
  <p data-lake-id="u02422f6a" id="u02422f6a"><br></p>
  <p data-lake-id="u462bfd2d" id="u462bfd2d"><span data-lake-id="u62273c10" id="u62273c10">举个例子，比如用户的明文密码是</span><code data-lake-id="ua64cd23f" id="ua64cd23f"><span data-lake-id="u9e707a61" id="u9e707a61">helloworld</span></code><span data-lake-id="u58bbe34a" id="u58bbe34a">，加密后的密文是</span><code data-lake-id="ud416dd17" id="ud416dd17"><span data-lake-id="u8a35f8de" id="u8a35f8de">xxeerrqq</span></code><span data-lake-id="u4c71430e" id="u4c71430e">。</span></p>
  <p data-lake-id="u2daaba6d" id="u2daaba6d"><br></p>
  <p data-lake-id="u5441ad42" id="u5441ad42"><span data-lake-id="u6e119905" id="u6e119905">用户注册：</span></p>
  <p data-lake-id="udac77671" id="udac77671"><br></p>
  <pre lang="java"><code>
helloworld -&gt; 加密 -&gt; xxeerrqq -&gt; 保存xxeerrqq到数据库中
</code></pre>
  <p data-lake-id="u9c85056e" id="u9c85056e"><br></p>
  <p data-lake-id="ub8fa6251" id="ub8fa6251"><span data-lake-id="u50675277" id="u50675277">用户登录</span></p>
  <p data-lake-id="uf048d41d" id="uf048d41d"><br></p>
  <pre lang="java"><code>
helloworld -&gt; 加密 -&gt; xxeerrqq -&gt; 使用xxeerrqq到数据库中匹配密码
</code></pre>
  <p data-lake-id="uc6b93176" id="uc6b93176"><br></p>
  <p data-lake-id="u4186f5bd" id="u4186f5bd"><span data-lake-id="u860b5eec" id="u860b5eec">密码加密技术经过很多年的发展，已经有了很多成熟的方案，这里就简单介绍几个。</span></p>
  <p data-lake-id="u0f54ee5c" id="u0f54ee5c"><br></p>
  <h3 data-lake-id="nhc15" id="nhc15"><span data-lake-id="u01e85407" id="u01e85407">对称加密</span></h3>
  <p data-lake-id="ud7921b03" id="ud7921b03"><br></p>
  <p data-lake-id="ufb0caa00" id="ufb0caa00"><span data-lake-id="uac98cb69" id="uac98cb69">对称加密，指的是需要对加密和解密使用相同密钥的加密算法。</span></p>
  <p data-lake-id="u07becaa1" id="u07becaa1"><br></p>
  <p data-lake-id="u0ebf06ed" id="u0ebf06ed"><span data-lake-id="u80773ae1" id="u80773ae1">最简单的对称加密算法就是通过ASCII码的变化进行密码保存，比如把</span><code data-lake-id="u8b51bc80" id="u8b51bc80"><span data-lake-id="u4e92a0f8" id="u4e92a0f8">abcde</span></code><span data-lake-id="uf936f375" id="uf936f375">转换成</span><code data-lake-id="ua285f8c1" id="ua285f8c1"><span data-lake-id="ucbb80e5a" id="ucbb80e5a">bcdef</span></code><span data-lake-id="ud2fa682f" id="ud2fa682f">，其加密算法就是把ASCII码增加1 。</span></p>
  <p data-lake-id="u62ff04f9" id="u62ff04f9"><br></p>
  <p data-lake-id="u7ece7478" id="u7ece7478"><span data-lake-id="u325a4a37" id="u325a4a37">这种加密算法，有一个特点，就是可以根据加密后得到的密文，再根据密钥还原出明文。</span></p>
  <p data-lake-id="u44296a28" id="u44296a28"><br></p>
  <p data-lake-id="u4d2f6602" id="u4d2f6602"><img src="http://www.hollischuang.com/wp-content/uploads/2019/01/15467502598358.jpg?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_28%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="udd05d729" id="udd05d729">​</span></p>
  <p data-lake-id="u75763edd" id="u75763edd"><br></p>
  <p data-lake-id="u28c77faa" id="u28c77faa"><span data-lake-id="u3da4db4a" id="u3da4db4a">但是，这种算法已经很少有网站在用了，虽然现在有很多方法可以把密钥单独保存，但是，既然黑客可以破解网站拿到用户的密文，就有可能也能获取到密钥。</span></p>
  <p data-lake-id="u7f11363e" id="u7f11363e"><br></p>
  <p data-lake-id="u1704e1d7" id="u1704e1d7"><span data-lake-id="ufcf481d2" id="ufcf481d2">在对称加密算法中常用的算法有：DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK等。</span></p>
  <p data-lake-id="uc5b64e38" id="uc5b64e38"><br></p>
  <h3 data-lake-id="kfRLR" id="kfRLR"><span data-lake-id="ube9c4f82" id="ube9c4f82">单向Hash算法</span></h3>
  <p data-lake-id="uf3341f6e" id="uf3341f6e"><br></p>
  <p data-lake-id="u2cb81fc7" id="u2cb81fc7"><span data-lake-id="ub0ec7180" id="ub0ec7180">单向散列算法，又称hash函数，就是把任意长的输入消息串变化成固定长的输出串的一种函数。一般用于产生消息摘要，密钥加密等。</span></p>
  <p data-lake-id="u754287a3" id="u754287a3"><br></p>
  <p data-lake-id="ud2cc49d5" id="ud2cc49d5"><span data-lake-id="ubfb58478" id="ubfb58478">单向Hash算法是一种无法通过计算还原出原始密码，而且实现比较简单的算法。</span></p>
  <p data-lake-id="u67697566" id="u67697566"><br></p>
  <p data-lake-id="u4f78d41e" id="u4f78d41e"><img src="http://www.hollischuang.com/wp-content/uploads/2019/01/15467486593905.jpg?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_28%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u1935ede0" id="u1935ede0">​</span></p>
  <p data-lake-id="udd344639" id="udd344639"><br></p>
  <p data-lake-id="u4affdfe5" id="u4affdfe5"><span data-lake-id="uf2b6eff8" id="uf2b6eff8">很多互联网公司都采用这种方式保存用户密码，曾经这种方式也是比较安全的方式。</span></p>
  <p data-lake-id="u82c571b4" id="u82c571b4"><br></p>
  <p data-lake-id="uc741421e" id="uc741421e"><span data-lake-id="uee999ff1" id="uee999ff1">常见散列函数(Hash函数)有： MD5（Message Digest Algorithm 5）、 SHA（Secure Hash Algorithm）、 MAC（Message Authentication Code）、 CRC（Cyclic Redundancy Check）</span></p>
  <p data-lake-id="u0246025f" id="u0246025f"><span data-lake-id="u6807df98" id="u6807df98">​</span><br></p>
  <p data-lake-id="u18bb4127" id="u18bb4127"><strong><span data-lake-id="uee3cea59" id="uee3cea59">严格意义上来说，单项哈希算法并不算加密算法，因为像MD5这种算法，他只能加密，没办法解密。</span></strong></p>
  <p data-lake-id="u9a942638" id="u9a942638"><br></p>
  <h3 data-lake-id="PfN31" id="PfN31"><span data-lake-id="u17c07476" id="u17c07476">彩虹表</span></h3>
  <p data-lake-id="u1924c740" id="u1924c740"><br></p>
  <p data-lake-id="uf5249c52" id="uf5249c52"><span data-lake-id="u1abd046f" id="u1abd046f">彩虹表(rainbow table)是一个用于加密散列函数逆运算的预先计算好的表，常用于破解加密过的密码散列。 查找表常常用于包含有限字符固定长度纯文本密码的加密。这是以空间换时间的典型实践，在每一次尝试都计算的暴力破解中使用更少的计算能力和更多的储存空间，但却比简单的每个输入一条散列的翻查表使用更少的储存空间和更多的计算性能。</span></p>
  <p data-lake-id="u2d9ee2bf" id="u2d9ee2bf"><br></p>
  <p data-lake-id="u1afab867" id="u1afab867"><img src="http://www.hollischuang.com/wp-content/uploads/2019/01/15467481684358.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_34%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u6dd6a002" id="u6dd6a002">​</span></p>
  <p data-lake-id="u61d6613a" id="u61d6613a"><br></p>
  <p data-lake-id="udedfcd13" id="udedfcd13"><span data-lake-id="u4222dcf6" id="u4222dcf6">通常情况下，当字段经过散列处理（如MD5），会生成一段散列值，而散列后的值一般是无法通过特定算法得到原始字段的。但是某些情况，比如一个大型的彩虹表，通过在表中搜索该MD5值，很有可能在极短的时间内找到该散列值对应的真实字段内容。</span></p>
  <p data-lake-id="u2f8c0546" id="u2f8c0546"><br></p>
  <h3 data-lake-id="PWDkD" id="PWDkD"><span data-lake-id="uc6c47e3e" id="uc6c47e3e">加盐Hash算法</span></h3>
  <p data-lake-id="u096cc8dc" id="u096cc8dc"><br></p>
  <p data-lake-id="u1bb03fb9" id="u1bb03fb9"><span data-lake-id="ucfa31e29" id="ucfa31e29">盐（Salt），在密码学中，是指在散列之前将散列内容（例如：密码）的任意固定位置插入特定的字符串。这个在散列中加入字符串的方式称为“加盐”。其作用是让加盐后的散列结果和没有加盐的结果不相同，在不同的应用情景中，这个处理可以增加额外的安全性。</span></p>
  <p data-lake-id="uded76ac4" id="uded76ac4"><br></p>
  <p data-lake-id="ud4759006" id="ud4759006"><span data-lake-id="uf7a828fc" id="uf7a828fc">加盐后的散列值，可以极大的降低由于用户数据被盗而带来的密码泄漏风险，即使通过彩虹表寻找到了散列后的数值所对应的原始内容，但是由于经过了加盐，插入的字符串扰乱了真正的密码，使得获得真实密码的概率大大降低。</span></p>
  <p data-lake-id="u726dd1aa" id="u726dd1aa"><br></p>
  <p data-lake-id="u4a164a90" id="u4a164a90"><img src="http://www.hollischuang.com/wp-content/uploads/2019/01/15467489652662.jpg?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_28%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u050f6ec4" id="u050f6ec4">​</span></p>
  <p data-lake-id="u2774ba4c" id="u2774ba4c"><br></p>
  <p data-lake-id="u4f8bfd6d" id="u4f8bfd6d"><span data-lake-id="uaeabd4e6" id="uaeabd4e6">对于加了“固定盐”的Hash算法，需要保护“盐”不能泄露，这就会遇到“保护对称密钥”一样的问题，一旦“盐”泄露，根据“盐”重新建立彩虹表可以进行破解。</span></p>
  <p data-lake-id="u8a095ee3" id="u8a095ee3"><br></p>
  <h3 data-lake-id="fdifm" id="fdifm"><span data-lake-id="ubaa00b09" id="ubaa00b09">PBKDF2算法</span></h3>
  <p data-lake-id="u8fc4c837" id="u8fc4c837"><br></p>
  <p data-lake-id="u37df378f" id="u37df378f"><span data-lake-id="u095be562" id="u095be562">PBKDF2算法，即Password-Based Key Derivation Function 2。PBKDF2简单而言就是将加盐Hash进行多次重复计算，这个次数是可选择的。</span></p>
  <p data-lake-id="ufc8970f5" id="ufc8970f5"><br></p>
  <p data-lake-id="uf888a5af" id="uf888a5af"><span data-lake-id="uc776ef53" id="uc776ef53">该算法原理大致相当于在Hash算法基础上增加</span><strong><span data-lake-id="u052cdf0d" id="u052cdf0d">随机盐</span></strong><span data-lake-id="u99810daf" id="u99810daf">，并进行</span><strong><span data-lake-id="uede5919a" id="uede5919a">多次Hash运算</span></strong><span data-lake-id="uecc94117" id="uecc94117">，随机盐使得彩虹表的建表难度大幅增加，而多次Hash也使得建表和破解的难度都大幅增加。</span></p>
  <p data-lake-id="u2a2a7a32" id="u2a2a7a32"><br></p>
  <p data-lake-id="u96e39e3b" id="u96e39e3b"><span data-lake-id="u18bb7eac" id="u18bb7eac">如果计算一次所需要的时间是1微秒，那么计算1百万次就需要1秒钟。假如攻击一个密码所需的彩虹表有1千万条，建立所对应的彩虹表所需要的时间就是115天。这个代价足以让大部分的攻击者忘而生畏。</span></p>
  <p data-lake-id="u368a9a20" id="u368a9a20"><br></p>
  <p data-lake-id="u9e1df87d" id="u9e1df87d"><img src="http://www.hollischuang.com/wp-content/uploads/2019/01/15467493143620.jpg?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_43%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"><span data-lake-id="u399fac6c" id="u399fac6c">​</span></p>
  <p data-lake-id="u11cb4176" id="u11cb4176"><br></p>
  <p data-lake-id="uf9a5fa9d" id="uf9a5fa9d"><span data-lake-id="ua5b96208" id="ua5b96208">美国政府机构已经将这个方法标准化，并且用于一些政府和军方的系统。 这个方案最大的优点是标准化，实现容易同时采用了久经考验的SHA算法。</span></p>
  <p data-lake-id="ue22d962e" id="ue22d962e"><br></p>
  <p data-lake-id="ub2fd3221" id="ub2fd3221"><span data-lake-id="ub0324276" id="ub0324276">还有很多算法也可以有效抵御彩虹表，常见的有bcrypt、scrypt等。</span></p>
  <p data-lake-id="u5ecdcc91" id="u5ecdcc91"><br></p>
  <h3 data-lake-id="cCjoI" id="cCjoI"><span data-lake-id="ua789a23a" id="ua789a23a">bcrypt</span></h3>
  <p data-lake-id="ub066d45c" id="ub066d45c"><br></p>
  <p data-lake-id="ubb84ca5e" id="ubb84ca5e"><span data-lake-id="ued1db8e7" id="ued1db8e7">bcrypt是专门为密码存储而设计的算法，基于Blowfish加密算法变形而来，由Niels Provos和David Mazières发表于1999年的USENIX。</span></p>
  <p data-lake-id="u4e178637" id="u4e178637"><br></p>
  <p data-lake-id="u8de9fb59" id="u8de9fb59"><span data-lake-id="u06b181ae" id="u06b181ae">实现中bcrypt会使用一个加盐的流程以防御彩虹表攻击，同时bcrypt还是适应性函数，它可以借由增加迭代之次数来抵御日益增进的计算机运算能力透过暴力法破解。</span></p>
  <p data-lake-id="u027955c1" id="u027955c1"><br></p>
  <p data-lake-id="u88414ff9" id="u88414ff9"><span data-lake-id="u0987bf0e" id="u0987bf0e">由bcrypt加密的文件可在所有支持的操作系统和处理器上进行转移。它的口令必须是8至56个字符，并将在内部被转化为448位的密钥。然而，所提供的所有字符都具有十分重要的意义。密码越强大，您的数据就越安全。</span></p>
  <p data-lake-id="uc2a54225" id="uc2a54225"><br></p>
  <p data-lake-id="ubb14bc2b" id="ubb14bc2b"><span data-lake-id="u7ae31d21" id="u7ae31d21">bcrypt经过了很多安全专家的仔细分析，使用在以安全著称的OpenBSD中，一般认为它比PBKDF2更能承受随着计算能力加强而带来的风险。bcrypt也有广泛的函数库支持，因此建议使用这种方式存储密码。</span></p>
  <p data-lake-id="u79f2037b" id="u79f2037b"><br></p>
  <p data-lake-id="u19850723" id="u19850723"><strong><span data-lake-id="u250d7955" id="u250d7955">Java中使用bcrypt</span></strong></p>
  <p data-lake-id="ubea4d97c" id="ubea4d97c"><br></p>
  <p data-lake-id="ua9123d16" id="ua9123d16"><span data-lake-id="ubc538620" id="ubc538620">可以在官网（</span><a href="http://www.mindrot.org/projects/jBCrypt/" target="_blank" data-lake-id="u0768467d" id="u0768467d"><span data-lake-id="uc1548b03" id="uc1548b03">http://www.mindrot.org/projects/jBCrypt/</span></a><span data-lake-id="ue2127f44" id="ue2127f44"> ）获取该算法的源代码。在Java中，可以直接使用以下方式进行加密：</span></p>
  <p data-lake-id="ud97363b0" id="ud97363b0"><br></p>
  <pre lang="java"><code>
public static void main(String[] args) throws NoSuchAlgorithmException

{
    String  originalPassword = "漫话编程";
    String generatedSecuredPasswordHash = BCrypt.hashpw(originalPassword, BCrypt.gensalt(12));
    System.out.println(generatedSecuredPasswordHash);

    boolean matched = BCrypt.checkpw(originalPassword, generatedSecuredPasswordHash);

    System.out.println(matched);

}
</code></pre>
  <p data-lake-id="u0760afbe" id="u0760afbe"><br></p>
  <h3 data-lake-id="tTwUQ" id="tTwUQ"><span data-lake-id="u8c780479" id="u8c780479">scrypt</span></h3>
  <p data-lake-id="uec08f2e2" id="uec08f2e2"><br></p>
  <p data-lake-id="udaa7e775" id="udaa7e775"><span data-lake-id="uda81a0e7" id="uda81a0e7">scrypt是由著名的FreeBSD黑客 Colin Percival为他的备份服务 Tarsnap开发的。</span></p>
  <p data-lake-id="uae0e2b13" id="uae0e2b13"><br></p>
  <p data-lake-id="u57c4f4c2" id="u57c4f4c2"><span data-lake-id="u548739fe" id="u548739fe">设计时考虑到大规模的客制硬件攻击而刻意设计需要大量内存运算。scrypt需要使用大量内存的原因来自于产生大量伪随机性（英语：pseudorandom）资料作为算法计算的基础。一旦这些资料被产生后，算法将会以伪随机性的顺序读取这些资料产生结果。因此最直接的实做方式将会需要大量内存将这些资料储存在内存内供算法计算。</span></p>
  <p data-lake-id="u6c60a387" id="u6c60a387"><br></p>
  <p data-lake-id="u85082b24" id="u85082b24"><span data-lake-id="ud5abe0bc" id="ud5abe0bc">scrypt不仅计算所需时间长，而且占用的内存也多，使得并行计算多个摘要异常困难，因此利用彩虹表进行暴力攻击更加困难。scrypt没有在生产环境中大规模应用，并且缺乏仔细的审察和广泛的函数库支持。但是，scrypt在算法层面只要没有破绽，它的安全性应该高于PBKDF2和bcrypt。</span></p>
  <p data-lake-id="u045fc1de" id="u045fc1de"><br></p>
  <p data-lake-id="uc7325397" id="uc7325397"><strong><span data-lake-id="u6d327208" id="u6d327208">Java中使用scrypt</span></strong></p>
  <p data-lake-id="u348296f1" id="u348296f1"><br></p>
  <p data-lake-id="u85eb6363" id="u85eb6363"><span data-lake-id="ucf4915cd" id="ucf4915cd">有一个Java实现的scrypt工具类库(</span><a href="https://github.com/wg/scrypt" target="_blank" data-lake-id="u6492e592" id="u6492e592"><span data-lake-id="ud5819ca6" id="ud5819ca6">https://github.com/wg/scrypt</span></a><span data-lake-id="ub81c4c5c" id="ub81c4c5c"> )可以直接使用。用法也比较简单：</span></p>
  <p data-lake-id="u3384cbfd" id="u3384cbfd"><br></p>
  <pre lang="java"><code>
public static void main(String[] args) {

    String originalPassword = "漫话编程";

    String generatedSecuredPasswordHash = SCryptUtil.scrypt(originalPassword, 16, 16, 16);
    System.out.println(generatedSecuredPasswordHash);

    boolean matched = SCryptUtil.check("漫话编程", generatedSecuredPasswordHash);
    System.out.println(matched);

    matched = SCryptUtil.check("漫画编程", generatedSecuredPasswordHash);
    System.out.println(matched);
}
</code></pre>
  <p data-lake-id="uac562e22" id="uac562e22"><br></p>
 </body>
</html>